package org.jmh.gift.servcie.impl;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.jmh.gift.doc.GiftDoc;
import org.jmh.gift.servcie.IGiftDocService;
import org.jmh.gift.vo.BucketVo;
import org.jmh.query.GiftDocQuery;
import org.jmh.util.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.jmh.gift.repository.HighlightResultMapper;

import java.util.*;

@Service
public class IGiftDocServiceImpl implements IGiftDocService {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private HighlightResultMapper highlightResultMapper;
    @Override
    public PageInfo<GiftDoc> page(GiftDocQuery query) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //分页条件
        builder.withPageable(PageRequest.of(query.getCurrentPage()-1, query.getPageSize()));
        //排序条件
        if (Objects.nonNull(query.getOrderField())&&Objects.nonNull(query.getOrderType())){
            String field = changedFile(query.getOrderField());
            builder.withSort(new FieldSortBuilder(field)
                    .order(query.getOrderType().equals("asc")? SortOrder.ASC:SortOrder.DESC));
        }
        //区间查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (Objects.nonNull(query.getMinPrice())) {
            boolQuery.filter(QueryBuilders.rangeQuery("minPrice").gte(query.getMinPrice()));
        }
        if (Objects.nonNull(query.getMaxPrice())){
            boolQuery.filter(QueryBuilders.rangeQuery("minPrice").lte(query.getMaxPrice()));
        }
        //关键字的分词查询
        if(StringUtils.isNotBlank(query.getKeyword()))
            boolQuery.must(QueryBuilders.matchQuery("name",query.getKeyword()));
        //添加高亮处理
        builder.withHighlightFields(new HighlightBuilder.Field("name")
                .preTags("<span style='color:red;'>")
                .postTags("</span>"));
        //聚合查询
        TermsAggregationBuilder brands = AggregationBuilders.terms("brands").field("brand")
                .order(BucketOrder.count(false)).size(50);
        TermsAggregationBuilder typeNames = AggregationBuilders.terms("typeNames").field("typeName")
                .order(BucketOrder.count(false)).size(50);
        builder.addAggregation(brands).addAggregation(typeNames);


        NativeSearchQuery searchQuery = builder.build();
        AggregatedPage<GiftDoc> giftDocs = elasticsearchTemplate.queryForPage(searchQuery, GiftDoc.class,highlightResultMapper);

        //解析统计结果集
        Map<String, Aggregation> aggregationMap = giftDocs.getAggregations().asMap();
        System.out.println(aggregationMap);
        //map遍历
        Set<String> strings = aggregationMap.keySet();

        Map<String, Object> map = new HashMap<>();
        for (String key : strings) {
            StringTerms aggregation = (StringTerms) aggregationMap.get(key);
            List<StringTerms.Bucket> buckets = aggregation.getBuckets();
            System.out.println(buckets);
            ArrayList<BucketVo> bucketVos = new ArrayList<>();
            for (StringTerms.Bucket bucket : buckets) {
                long docCount = bucket.getDocCount();
                String bucketKey = bucket.getKeyAsString();
                BucketVo bucketVo = new BucketVo(docCount,bucketKey);
                bucketVos.add(bucketVo);
            }
            map.put(key,bucketVos);
        }

        //数据的总条数
        long totalElements = giftDocs.getTotalElements();
        //获取当前页的数据
        List<GiftDoc> content = giftDocs.getContent();
        return new PageInfo<>(totalElements, content, map);

    }


    private String changedFile(String orderField) {
        switch (orderField){
            case "no": return "onsaletime";
            case "jg": return "costprice";
            case "cl": return "reigstertime";
            case "lc": return "mileage";
        }
        return "";
    }
}
